package cn.jw.starter.game.common.time;

import java.time.LocalDateTime;

import cn.hutool.core.date.LocalDateTimeUtil;

/**
 * 在游戏开发中，经常遇到的一个时间问题是，计算某些场景的时间跨天重置时，不是按自然时间的0点计算跨开，还是按某个时间点计算跨天
 * 比如，在每天的凌晨5点才算跨天。此工具的功能就是来实现这个功能，可以指定任意一个时间点作为跨天的参考点。
 *
 * @author 王广帅
 * @since 2024/7/23 21:30
 */
public class GameDayBetweenUtil {

    /**
     * 一天时间的毫秒数
     */
    private static final long ONE_DAY_TIME = 24 * 60 * 60 * 1000;

    /**
     * 跨天时间点相对零点的偏移量，默认是5，表示在每天的5点算跨天
     */
    private static int offsiteHour = 5;

    /**
     * 此工具类默认的跨天时间点是凌晨5点，如果某个系统中的跨天时间不是5点，可以调用此方法，修改默认的跨天时间点
     * 
     * @param offsiteHour
     *            时间偏移量，单位小时
     */
    public static void setOffsiteHour(int offsiteHour) {
        GameDayBetweenUtil.offsiteHour = offsiteHour;
    }

    public static int getBetweenGameDay(long time1, long time2) {
        return getBetweenGameDay(LocalDateTimeUtil.of(time1), LocalDateTimeUtil.of(time2));
    }

    /**
     * 计算两个时间点在游戏中相差的天数。
     * <ul>
     * <li>2. 计算t1,t2两个时间点相差的自然天数n = （t2-t1）/(24 * 60 * 60 * 1000)</li>
     * <li>3. 再计算time1,time2两个时间点不足一天的部分，即当前的小时数,得到h1,h2两个值</li>
     * <li>h1和h2如果一个在偏移量左边，一个在偏移量右边，则跨了新的一天</li>
     * </ul>
     * 
     * @param lt1
     *            时间点1，单位毫秒
     * @param lt2
     *            时间点2，单位毫秒
     * 
     * @return 两个时间点相差的天数，一定是一个正值
     */
    public static int getBetweenGameDay(LocalDateTime lt1, LocalDateTime lt2) {
        int betweenGameDays = (int)(lt2.toLocalDate().toEpochDay() - lt1.toLocalDate().toEpochDay());
        // 取绝对值，保证为正数
        betweenGameDays = Math.abs(betweenGameDays);

        int h1 = lt1.getHour() - offsiteHour;
        int h2 = lt2.getHour() - offsiteHour;
        if ((h1 < 0 && h2 >= 0)) {
            // 跨天了
            betweenGameDays += 1;
        } else if (h1 >= 0 && h2 < 0) {
            betweenGameDays -= 1;
        }

        return betweenGameDays;

    }

}
